/*
 * G2P_SyllableTree.h
 *
 *  Created on: Nov 19, 2012
 *      Author: Pongsathon Janyoi
 */
#ifndef G2P_SY_H_
#define G2P_SY_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "g2p_pronun_struct.h"

#define SYLLABLE_PROB_SIZE 30
#define SYLLABLE_STACK_PROB_SIZE 50
#define SYLLABLE_PROB_TABLE_SIZE 50
struct _syllable_node_prob;
struct _syllable_node;

typedef struct _syllable_prob_table{
	int pst_id;
	struct _syllable_node * parent;
	struct _syllable_node * child;
	int par_id;
	int cst_id;
	float prob;
	int path;
}syllable_prob_table;

typedef struct _syllable_prob_bundle{
	syllable_prob_table * prob_chain[SYLLABLE_PROB_TABLE_SIZE];
	float prob;
	int max_size;
	int size;
}syllable_prob_bundle;
typedef struct _syllable_node{
	bool root;
	char * text;

	struct _syllable_node *parent[20];	/* parent node */
	struct _syllable_node *child[20];		/* child node */
	pronun_struct * struc;				/* structure */
	int child_size;						/* number of child */
	int parent_size;					/* number of parent */
	int text_len;						/* length of text */
	int path_len;						/* sum all length from parent to this node */
	syllable_prob_table * prob_tab[SYLLABLE_PROB_TABLE_SIZE];	/* probability with parent */
	int prob_tab_row;					/* amount of prob */
	int prob_tab_max;					/* maximum of prob row */
	bool cal_prob;						/* flag remember a calculate prob node */
	int tone_mk;
	bool traversal;
}syllable_node;

typedef struct _syllable_maximum{
	pronun_struct_unit * unit;
}syllable_maximum;
typedef struct _syllable_maximum_pair{
	pronun_struct_unit ** unit;
	float prob;
	int size;
}syllable_maximum_pair;

typedef struct _syllable_stack{
	syllable_node  ** element;
	int sum_len;
	int size;
}syllable_stack;
typedef struct _syllable_stack_tab{
	syllable_prob_table * element[1024];
	int size;
}syllable_stack_tab;

typedef struct _syllable_node_prob{
	unsigned int st_parent1;
	unsigned int st_parent2;
	syllable_node * child;
	unsigned int st_child;
	float prob;
}syllable_node_prob;

typedef struct _syllable_seq_unit{

	unsigned int sylcode;	//code
	int c; //first conso group
	int wt;
	int mt;
	int tone;
	int wdnum;
	char src;
}syllable_seq_unit;
typedef struct _syllable_seq{
	char wseg[512];
	syllable_seq_unit ** seq;
	int size;
	int mex_size;
}syllable_seq;

#define MAX_LINE_LEN 1025
syllable_node * syllable_tree_create_node(char * text);
syllable_node * syllable_tree_add_child(syllable_node * parent,syllable_node * new_node);
syllable_node * syllable_tree_add_parent(syllable_node * parent,syllable_node * new_node);
syllable_node * syllable_tree_remove_child(syllable_node * parent,syllable_node * new_node);
void * syllable_tree_print(syllable_node * node,char ** out_text,int level,int *max,int parent_id);
void * syllable_tree_print_result(char ** out_text,int max);

/*
void syllable_stack_push(syllable_node * node);
void syllable_stack_create();
void syllable_stack_print();
void syllable_stack_clear();*/
syllable_stack * syllable_stack_create();
void syllable_stack_push(syllable_stack * stack, syllable_node * node);
void syllable_stack_clear(syllable_stack * stack);
void syllable_stack_print(syllable_stack * stack);
syllable_node * syllable_stack_find(syllable_stack * stack,int len);
syllable_node * syllable_stack_find(int len);


syllable_prob_bundle * syllable_create_prob_bundle(int max_size);
syllable_prob_bundle * syllable_clone_prob_bundle(syllable_prob_bundle * b1);
void syllable_free_prob_bundle(syllable_prob_bundle * b);
void syllable_prob_bundle_print(syllable_prob_bundle * b1,_IO_FILE * t);
void syllable_prob_bundle2phoneme(syllable_prob_bundle * b1,char * out_phone);
void syllable_prob_bundle2phoneme_code(syllable_prob_bundle * b1,char * out_phone);
syllable_prob_table ** syllable_create_prob_table(syllable_node * node ,int max_size);
void syllable_prob_maximum_print(syllable_maximum_pair * pair);

syllable_stack_tab * syllable_create_stack_prob_table(int max_size);
void syllable_print_stack_prob_table(	syllable_stack_tab * stack);
void syllable_free_stack_prob_table(syllable_stack_tab * stack);

//for test
void syllable_prob_bundle2phoneme_tone_analysis(syllable_prob_bundle * b1,char * out_phone);

//
syllable_seq_unit * syllable_seq_unit_create();
syllable_seq * syllable_seq_create(int size);
void syllable_seq_add(syllable_seq * parent,syllable_seq_unit * node);
void syllable_seq_cat(syllable_seq * s1,syllable_seq * s2);
void syllable_seq_print(syllable_seq * s);
void syllable_prob_bundle2sylseq(syllable_prob_bundle * b1,
		syllable_seq * seq,int wnum);
void syllable_prob_sylseq_predict_tone(syllable_seq * seq);
int syllable_seq_free(syllable_seq * seq );

#endif
